gtk-launch: add hack to close up dbus-daemon race
authorRay Strode <rstrode@redhat.com>
Fri, 4 Mar 2016 15:02:34 +0000 (10:02 -0500)
committerRay Strode <rstrode@redhat.com>
Fri, 4 Mar 2016 17:42:37 +0000 (12:42 -0500)
If gtk-launch exits before the program it starts fully activates,
then the dbus-daemon may avoid doing the activating method call.

This commit works around the problem by pinging the activated
application, and waiting for a reply.

This is similar to the gvfs-open bug here:

    https://bugzilla.gnome.org/show_bug.cgi?id=746534

https://bugzilla.gnome.org/show_bug.cgi?id=763103

gtk/gtk-launch.c

index 576a449559b36e139a099a96065451493b84e904..4186a45ea989527df14e47699ab9c19ae38c1de5 100644 (file)
@@ -51,6 +51,7 @@ main (int argc, char *argv[])
   gchar *app_name;
 #ifdef G_OS_UNIX
   gchar *desktop_file_name;
+  gchar *bus_name = NULL;
 #endif
   GAppInfo *info = NULL;
   GAppLaunchContext *launch_context;
@@ -119,10 +120,19 @@ main (int argc, char *argv[])
 
   app_name = *args;
 #ifdef G_OS_UNIX
+  bus_name = g_strdup (app_name);
   if (g_str_has_suffix (app_name, ".desktop"))
-    desktop_file_name = g_strdup (app_name);
+    {
+      desktop_file_name = g_strdup (app_name);
+      bus_name[strlen (bus_name) - strlen(".desktop")] = '\0';
+    }
   else
-    desktop_file_name = g_strconcat (app_name, ".desktop", NULL);
+    {
+      desktop_file_name = g_strconcat (app_name, ".desktop", NULL);
+    }
+
+  if (!g_dbus_is_name (bus_name))
+    g_clear_pointer (&bus_name, g_free);
   info = G_APP_INFO (g_desktop_app_info_new (desktop_file_name));
   g_free (desktop_file_name);
 #else
@@ -159,6 +169,33 @@ main (int argc, char *argv[])
     }
   g_object_unref (info);
   g_object_unref (launch_context);
+
+#ifdef G_OS_UNIX
+  if (bus_name != NULL)
+    {
+      GDBusConnection *connection;
+      gchar *object_path, *p;
+
+      connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
+
+      object_path = g_strdup_printf ("/%s", bus_name);
+      for (p = object_path; *p != '\0'; p++)
+          if (*p == '.')
+              *p = '/';
+
+      if (connection)
+        g_dbus_connection_call_sync (connection,
+                                     bus_name,
+                                     object_path,
+                                     "org.freedesktop.DBus.Peer",
+                                     "Ping",
+                                     NULL, NULL,
+                                     G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL);
+      g_clear_pointer (&object_path, g_free);
+      g_clear_object (&connection);
+      g_clear_pointer (&bus_name, g_free);
+    }
+#endif
   g_list_free_full (l, g_object_unref);
 
   return 0;